{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bfda947b",
   "metadata": {},
   "source": [
    "* 记录人：廖洪恩  \n",
    "* 记录时间：2022年5月10日   \n",
    "* 记录内容：语音识别   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "515f57e9",
   "metadata": {},
   "source": [
    "# 本周内容  \n",
    "## 知识概念  \n",
    "> 1.一切都是I/O：软工到产品的一般化知识  \n",
    "> 2.语音识别:speech recognition  \n",
    "> 3.语音唤醒  \n",
    "> 4.自动语音识别:Automatic Speech Recognition, 简称 ASR  \n",
    ">> (1).其目标是以电脑自动将人类的语音内容转换为相应的文字。与说话人识别及说话人确认不同，后者尝试识别或确认发出语音的说话人而非其中所包含的>  \n",
    "> 5.语音合成:text to speech,简称 TTS   \n",
    ">> (1).将文字转化为语音的一种技术，类似于人类的嘴巴，通过不同的音色说出想表达的内容。 在语音合成技术中，主要分为 语言分析部分 和 声学系统部分 ，也称为 前端部分 和 后端部分， 语言分析部分主要是根据输入的文字信息进行分析，生成对应的语言学规格书，想好该怎么读；声学系统部分主要是根据语音分析部分提供的语音学规格书，生成对应的音频，实现发声的功能。   \n",
    "> 6.课堂视频资源  \n",
    ">> (1).一分钟看懂语音识别  \n",
    "> 7.语音识别、语音合成都被用在哪儿？   \n",
    ">> (1).杭州阿里巴巴高科技无人酒店，入住全程靠脸！   \n",
    "[语音助手敢和真人打电话！(演示+中文字幕)](06_Google\\ 2018.mp4)   \n",
    "「ZEALER 特别企划 」语音识别  \n",
    "苹果 小米 华为 天猫 百度，入门款对比测试，谁的表现更胜一筹？   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ad7e123",
   "metadata": {},
   "source": [
    "## 课堂视频资源  \n",
    "* 一分钟看懂语音识别：https://www.bilibili.com/video/BV1Lx41177sY?spm_id_from=333.999.0.0  \n",
    "* 语音识别、语音合成都被用在哪儿？：https://www.bilibili.com/video/BV1jt411p72z?spm_id_from=333.999.0.0      \n",
    "* 杭州阿里巴巴高科技无人酒店，入住全程靠脸：https://www.bilibili.com/video/BV1Sb411y7hj?spm_id_from=333.337.search-card.all.click   \n",
    "* [语音助手敢和真人打电话！(演示+中文字幕)](06_Google\\ 2018.mp4)     \n",
    "* 「ZEALER 特别企划 」语音识别：https://www.bilibili.com/video/BV1vs411k7g8?spm_id_from=333.999.0.0  \n",
    "* 苹果 小米 华为 天猫 百度，入门款对比测试，谁的表现更胜一筹？：https://www.bilibili.com/video/BV1m64y1t7Lf?spm_id_from=333.337.search-card.all.click "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "967b0d00",
   "metadata": {},
   "source": [
    "# 语音识别测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4546976e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"refresh_token\":\"25.32b2191e6956632b12dfb373df4747cd.315360000.1969069567.282335-26195899\",\"expires_in\":2592000,\"session_key\":\"9mzdDxLNWpKS+aL+MgTDgo74mXsP\\/uIK2ZzDhgLXpIT6LocGWh+npkIFQ44zgiCQEdhuMB3WHXgMpdYJE9PugMzghX67GA==\",\"access_token\":\"24.462127d3f0bf49bea31edca18581b5d8.2592000.1656301567.282335-26195899\",\"scope\":\"audio_voice_assistant_get brain_enhanced_asr audio_tts_post brain_speech_realtime public brain_all_scope brain_asr_async wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test\\u6743\\u9650 vis-classify_flower lpq_\\u5f00\\u653e cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base smartapp_mapp_dev_manage iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_\\u5f00\\u653eScope vis-ocr_\\u865a\\u62df\\u4eba\\u7269\\u52a9\\u7406 idl-video_\\u865a\\u62df\\u4eba\\u7269\\u52a9\\u7406 smartapp_component smartapp_search_plugin avatar_video_test b2b_tp_openapi b2b_tp_openapi_online smartapp_gov_aladin_to_xcx\",\"session_secret\":\"9530aac89c7cf8504a2f3eef4090778c\"}\n",
      "\n",
      "{'refresh_token': '25.32b2191e6956632b12dfb373df4747cd.315360000.1969069567.282335-26195899', 'expires_in': 2592000, 'session_key': '9mzdDxLNWpKS+aL+MgTDgo74mXsP/uIK2ZzDhgLXpIT6LocGWh+npkIFQ44zgiCQEdhuMB3WHXgMpdYJE9PugMzghX67GA==', 'access_token': '24.462127d3f0bf49bea31edca18581b5d8.2592000.1656301567.282335-26195899', 'scope': 'audio_voice_assistant_get brain_enhanced_asr audio_tts_post brain_speech_realtime public brain_all_scope brain_asr_async wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test权限 vis-classify_flower lpq_开放 cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base smartapp_mapp_dev_manage iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_开放Scope vis-ocr_虚拟人物助理 idl-video_虚拟人物助理 smartapp_component smartapp_search_plugin avatar_video_test b2b_tp_openapi b2b_tp_openapi_online smartapp_gov_aladin_to_xcx', 'session_secret': '9530aac89c7cf8504a2f3eef4090778c'}\n",
      "SUCCESS WITH TOKEN: 24.462127d3f0bf49bea31edca18581b5d8.2592000.1656301567.282335-26195899 ; EXPIRES IN SECONDS: 2592000\n",
      "url is http://vop.baidu.com/server_api?cuid=123456PYTHON&token=24.462127d3f0bf49bea31edca18581b5d8.2592000.1656301567.282335-26195899&dev_pid=1537\n",
      "header is {'Content-Type': 'audio/pcm; rate=16000', 'Content-Length': 129600}\n",
      "Request time cost 1.429194\n",
      "{\"corpus_no\":\"7102628512513775666\",\"err_msg\":\"success.\",\"err_no\":0,\"result\":[\"北京科技馆。\"],\"sn\":\"27454893631653709568\"}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# coding=utf-8\n",
    "\n",
    "import sys\n",
    "import json\n",
    "import time\n",
    "\n",
    "IS_PY3 = sys.version_info.major == 3\n",
    "\n",
    "if IS_PY3:\n",
    "    from urllib.request import urlopen\n",
    "    from urllib.request import Request\n",
    "    from urllib.error import URLError\n",
    "    from urllib.parse import urlencode\n",
    "\n",
    "    timer = time.perf_counter\n",
    "else:\n",
    "    import urllib2\n",
    "    from urllib2 import urlopen\n",
    "    from urllib2 import Request\n",
    "    from urllib2 import URLError\n",
    "    from urllib import urlencode\n",
    "\n",
    "    if sys.platform == \"win32\":\n",
    "        timer = time.clock\n",
    "    else:\n",
    "        # On most other platforms the best timer is time.time()\n",
    "        timer = time.time\n",
    "\n",
    "API_KEY = '5hhk3ClVlyVDs6BoaQT75HYC'\n",
    "SECRET_KEY = 'nGhPUpw0uOxcq60auHEcB56ErhAoqMbX'\n",
    "\n",
    "# 需要识别的文件\n",
    "AUDIO_FILE = './audio/16k.pcm'  # 只支持 pcm/wav/amr 格式，极速版额外支持m4a 格式\n",
    "# 文件格式\n",
    "FORMAT = AUDIO_FILE[-3:];  # 文件后缀只支持 pcm/wav/amr 格式，极速版额外支持m4a 格式\n",
    "\n",
    "CUID = '123456PYTHON';\n",
    "# 采样率\n",
    "RATE = 16000;  # 固定值\n",
    "\n",
    "# 普通版\n",
    "\n",
    "DEV_PID = 1537;  # 1537 表示识别普通话，使用输入法模型。根据文档填写PID，选择语言及识别模型\n",
    "ASR_URL = 'http://vop.baidu.com/server_api'\n",
    "SCOPE = 'audio_voice_assistant_get'  # 有此scope表示有asr能力，没有请在网页里勾选，非常旧的应用可能没有\n",
    "\n",
    "#测试自训练平台需要打开以下信息， 自训练平台模型上线后，您会看见 第二步：“”获取专属模型参数pid:8001，modelid:1234”，按照这个信息获取 dev_pid=8001，lm_id=1234\n",
    "# DEV_PID = 8001 ;   \n",
    "# LM_ID = 1234 ;\n",
    "\n",
    "# 极速版 打开注释的话请填写自己申请的appkey appSecret ，并在网页中开通极速版（开通后可能会收费）\n",
    "\n",
    "#DEV_PID = 80001\n",
    "#ASR_URL = 'http://vop.baidu.com/pro_api'\n",
    "#SCOPE = 'brain_enhanced_asr'  # 有此scope表示有asr能力，没有请在网页里开通极速版\n",
    "\n",
    "# 忽略scope检查，非常旧的应用可能没有\n",
    "# SCOPE = False\n",
    "\n",
    "\n",
    "# 极速版\n",
    "\n",
    "class DemoError(Exception):\n",
    "    pass\n",
    "\n",
    "\n",
    "\"\"\"  TOKEN start \"\"\"\n",
    "\n",
    "TOKEN_URL = 'http://aip.baidubce.com/oauth/2.0/token'\n",
    "\n",
    "\n",
    "def fetch_token():\n",
    "    params = {'grant_type': 'client_credentials',\n",
    "              'client_id': API_KEY,\n",
    "              'client_secret': SECRET_KEY}\n",
    "    post_data = urlencode(params)\n",
    "    if (IS_PY3):\n",
    "        post_data = post_data.encode('utf-8')\n",
    "    req = Request(TOKEN_URL, post_data)\n",
    "    try:\n",
    "        f = urlopen(req)\n",
    "        result_str = f.read()\n",
    "    except URLError as err:\n",
    "        print('token http response http code : ' + str(err.code))\n",
    "        result_str = err.read()\n",
    "    if (IS_PY3):\n",
    "        result_str = result_str.decode()\n",
    "\n",
    "    print(result_str)\n",
    "    result = json.loads(result_str)\n",
    "    print(result)\n",
    "    if ('access_token' in result.keys() and 'scope' in result.keys()):\n",
    "        if SCOPE and (not SCOPE in result['scope'].split(' ')):  # SCOPE = False 忽略检查\n",
    "            raise DemoError('scope is not correct')\n",
    "        print('SUCCESS WITH TOKEN: %s ; EXPIRES IN SECONDS: %s' % (result['access_token'], result['expires_in']))\n",
    "        return result['access_token']\n",
    "    else:\n",
    "        raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response')\n",
    "\n",
    "\n",
    "\"\"\"  TOKEN end \"\"\"\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    token = fetch_token()\n",
    "\n",
    "    \"\"\"\n",
    "    httpHandler = urllib2.HTTPHandler(debuglevel=1)\n",
    "    opener = urllib2.build_opener(httpHandler)\n",
    "    urllib2.install_opener(opener)\n",
    "    \"\"\"\n",
    "\n",
    "    speech_data = []\n",
    "    with open(AUDIO_FILE, 'rb') as speech_file:\n",
    "        speech_data = speech_file.read()\n",
    "    length = len(speech_data)\n",
    "    if length == 0:\n",
    "        raise DemoError('file %s length read 0 bytes' % AUDIO_FILE)\n",
    "\n",
    "    params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID}\n",
    "    #测试自训练平台需要打开以下信息\n",
    "    #params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID, 'lm_id' : LM_ID}\n",
    "    params_query = urlencode(params);\n",
    "\n",
    "    headers = {\n",
    "        'Content-Type': 'audio/' + FORMAT + '; rate=' + str(RATE),\n",
    "        'Content-Length': length\n",
    "    }\n",
    "\n",
    "    url = ASR_URL + \"?\" + params_query\n",
    "    print(\"url is\", url);\n",
    "    print(\"header is\", headers)\n",
    "    # print post_data\n",
    "    req = Request(ASR_URL + \"?\" + params_query, speech_data, headers)\n",
    "    try:\n",
    "        begin = timer()\n",
    "        f = urlopen(req)\n",
    "        result_str = f.read()\n",
    "        print(\"Request time cost %f\" % (timer() - begin))\n",
    "    except  URLError as err:\n",
    "        print('asr http response http code : ' + str(err.code))\n",
    "        result_str = err.read()\n",
    "\n",
    "    if (IS_PY3):\n",
    "        result_str = str(result_str, 'utf-8')\n",
    "    print(result_str)\n",
    "    with open(\"result.txt\", \"w\") as of:\n",
    "        of.write(result_str)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c783c41",
   "metadata": {},
   "source": [
    "# 语音合成接口测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3a017e9b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fetch token begin\n",
      "{\"refresh_token\":\"25.642e14ce2bd21a2899806d131909a5ba.315360000.1969071368.282335-26335266\",\"expires_in\":2592000,\"session_key\":\"9mzdDc7kkEzgouo6ldTMx\\/IPKyZ7E94AJ7kYJquUPoLhxwDcQdRJY4yG0D0tvwaYU+Uqbq4UMaQ8bYJnFxypBOG6LegJbg==\",\"access_token\":\"24.6811d67e36897402d7b9eeccf502d0f7.2592000.1656303368.282335-26335266\",\"scope\":\"audio_voice_assistant_get brain_enhanced_asr audio_tts_post brain_speech_realtime public brain_all_scope brain_asr_async wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test\\u6743\\u9650 vis-classify_flower lpq_\\u5f00\\u653e cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base smartapp_mapp_dev_manage iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_\\u5f00\\u653eScope vis-ocr_\\u865a\\u62df\\u4eba\\u7269\\u52a9\\u7406 idl-video_\\u865a\\u62df\\u4eba\\u7269\\u52a9\\u7406 smartapp_component smartapp_search_plugin avatar_video_test b2b_tp_openapi b2b_tp_openapi_online smartapp_gov_aladin_to_xcx\",\"session_secret\":\"3c78cd530cfbde5474aa61ced7b649a4\"}\n",
      "\n",
      "{'refresh_token': '25.642e14ce2bd21a2899806d131909a5ba.315360000.1969071368.282335-26335266', 'expires_in': 2592000, 'session_key': '9mzdDc7kkEzgouo6ldTMx/IPKyZ7E94AJ7kYJquUPoLhxwDcQdRJY4yG0D0tvwaYU+Uqbq4UMaQ8bYJnFxypBOG6LegJbg==', 'access_token': '24.6811d67e36897402d7b9eeccf502d0f7.2592000.1656303368.282335-26335266', 'scope': 'audio_voice_assistant_get brain_enhanced_asr audio_tts_post brain_speech_realtime public brain_all_scope brain_asr_async wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian ApsMisTest_Test权限 vis-classify_flower lpq_开放 cop_helloScope ApsMis_fangdi_permission smartapp_snsapi_base smartapp_mapp_dev_manage iop_autocar oauth_tp_app smartapp_smart_game_openapi oauth_sessionkey smartapp_swanid_verify smartapp_opensource_openapi smartapp_opensource_recapi fake_face_detect_开放Scope vis-ocr_虚拟人物助理 idl-video_虚拟人物助理 smartapp_component smartapp_search_plugin avatar_video_test b2b_tp_openapi b2b_tp_openapi_online smartapp_gov_aladin_to_xcx', 'session_secret': '3c78cd530cfbde5474aa61ced7b649a4'}\n",
      "SUCCESS WITH TOKEN: 24.6811d67e36897402d7b9eeccf502d0f7.2592000.1656303368.282335-26335266 ; EXPIRES IN SECONDS: 2592000\n",
      "%E6%AC%A2%E8%BF%8E%E4%BD%BF%E7%94%A8%E7%99%BE%E5%BA%A6%E8%AF%AD%E9%9F%B3%E5%90%88%E6%88%90%E3%80%82\n",
      "test on Web Browserhttp://tsn.baidu.com/text2audio?tok=24.6811d67e36897402d7b9eeccf502d0f7.2592000.1656303368.282335-26335266&tex=%25E6%25AC%25A2%25E8%25BF%258E%25E4%25BD%25BF%25E7%2594%25A8%25E7%2599%25BE%25E5%25BA%25A6%25E8%25AF%25AD%25E9%259F%25B3%25E5%2590%2588%25E6%2588%2590%25E3%2580%2582&per=4&spd=5&pit=5&vol=5&aue=3&cuid=123456PYTHON&lan=zh&ctp=1\n",
      "result saved as :result.mp3\n"
     ]
    }
   ],
   "source": [
    "# coding=utf-8\n",
    "import sys\n",
    "import json\n",
    "\n",
    "IS_PY3 = sys.version_info.major == 3\n",
    "if IS_PY3:\n",
    "    from urllib.request import urlopen\n",
    "    from urllib.request import Request\n",
    "    from urllib.error import URLError\n",
    "    from urllib.parse import urlencode\n",
    "    from urllib.parse import quote_plus\n",
    "else:\n",
    "    import urllib2\n",
    "    from urllib import quote_plus\n",
    "    from urllib2 import urlopen\n",
    "    from urllib2 import Request\n",
    "    from urllib2 import URLError\n",
    "    from urllib import urlencode\n",
    "\n",
    "API_KEY = 'AeoA7xv8HrKccxGTxAgF9Mfs'\n",
    "SECRET_KEY = 'sMUPLsymFlcRBpz2WHxvFvgKNcdvd5Va'\n",
    "\n",
    "TEXT = \"欢迎使用百度语音合成。\"\n",
    "\n",
    "# 发音人选择, 基础音库：0为度小美，1为度小宇，3为度逍遥，4为度丫丫，\n",
    "# 精品音库：5为度小娇，103为度米朵，106为度博文，110为度小童，111为度小萌，默认为度小美 \n",
    "PER = 4\n",
    "# 语速，取值0-15，默认为5中语速\n",
    "SPD = 5\n",
    "# 音调，取值0-15，默认为5中语调\n",
    "PIT = 5\n",
    "# 音量，取值0-9，默认为5中音量\n",
    "VOL = 5\n",
    "# 下载的文件格式, 3：mp3(default) 4： pcm-16k 5： pcm-8k 6. wav\n",
    "AUE = 3\n",
    "\n",
    "FORMATS = {3: \"mp3\", 4: \"pcm\", 5: \"pcm\", 6: \"wav\"}\n",
    "FORMAT = FORMATS[AUE]\n",
    "\n",
    "CUID = \"123456PYTHON\"\n",
    "\n",
    "TTS_URL = 'http://tsn.baidu.com/text2audio'\n",
    "\n",
    "\n",
    "class DemoError(Exception):\n",
    "    pass\n",
    "\n",
    "\n",
    "\"\"\"  TOKEN start \"\"\"\n",
    "\n",
    "TOKEN_URL = 'http://aip.baidubce.com/oauth/2.0/token'\n",
    "SCOPE = 'audio_tts_post'  # 有此scope表示有tts能力，没有请在网页里勾选\n",
    "\n",
    "\n",
    "def fetch_token():\n",
    "    print(\"fetch token begin\")\n",
    "    params = {'grant_type': 'client_credentials',\n",
    "              'client_id': API_KEY,\n",
    "              'client_secret': SECRET_KEY}\n",
    "    post_data = urlencode(params)\n",
    "    if (IS_PY3):\n",
    "        post_data = post_data.encode('utf-8')\n",
    "    req = Request(TOKEN_URL, post_data)\n",
    "    try:\n",
    "        f = urlopen(req, timeout=5)\n",
    "        result_str = f.read()\n",
    "    except URLError as err:\n",
    "        print('token http response http code : ' + str(err.code))\n",
    "        result_str = err.read()\n",
    "    if (IS_PY3):\n",
    "        result_str = result_str.decode()\n",
    "\n",
    "    print(result_str)\n",
    "    result = json.loads(result_str)\n",
    "    print(result)\n",
    "    if ('access_token' in result.keys() and 'scope' in result.keys()):\n",
    "        if not SCOPE in result['scope'].split(' '):\n",
    "            raise DemoError('scope is not correct')\n",
    "        print('SUCCESS WITH TOKEN: %s ; EXPIRES IN SECONDS: %s' % (result['access_token'], result['expires_in']))\n",
    "        return result['access_token']\n",
    "    else:\n",
    "        raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response')\n",
    "\n",
    "\n",
    "\"\"\"  TOKEN end \"\"\"\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    token = fetch_token()\n",
    "    tex = quote_plus(TEXT)  # 此处TEXT需要两次urlencode\n",
    "    print(tex)\n",
    "    params = {'tok': token, 'tex': tex, 'per': PER, 'spd': SPD, 'pit': PIT, 'vol': VOL, 'aue': AUE, 'cuid': CUID,\n",
    "              'lan': 'zh', 'ctp': 1}  # lan ctp 固定参数\n",
    "\n",
    "    data = urlencode(params)\n",
    "    print('test on Web Browser' + TTS_URL + '?' + data)\n",
    "\n",
    "    req = Request(TTS_URL, data.encode('utf-8'))\n",
    "    has_error = False\n",
    "    try:\n",
    "        f = urlopen(req)\n",
    "        result_str = f.read()\n",
    "\n",
    "        headers = dict((name.lower(), value) for name, value in f.headers.items())\n",
    "\n",
    "        has_error = ('content-type' not in headers.keys() or headers['content-type'].find('audio/') < 0)\n",
    "    except  URLError as err:\n",
    "        print('asr http response http code : ' + str(err.code))\n",
    "        result_str = err.read()\n",
    "        has_error = True\n",
    "\n",
    "    save_file = \"error.txt\" if has_error else 'result.' + FORMAT\n",
    "    with open(save_file, 'wb') as of:\n",
    "        of.write(result_str)\n",
    "\n",
    "    if has_error:\n",
    "        if (IS_PY3):\n",
    "            result_str = str(result_str, 'utf-8')\n",
    "        print(\"tts api  error:\" + result_str)\n",
    "\n",
    "    print(\"result saved as :\" + save_file)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5af8a097",
   "metadata": {},
   "source": [
    "# 真对话机器人（文本回复）  \n",
    "* 1.识别语音-->转换百度语音识别指定格式文件  \n",
    "* 2.调用百度asr接口，转换成文本  \n",
    "* 3.回复？数据结构：字典 {key:value} , key（人） 作为输入 Input, value（机器） 作为 Output  \n",
    "{\"你好呀\":\"你也好呀，看起来心情不错呀！\"}  \n",
    "  \n",
    "* 4.回复value的信息   \n",
    "* 5.接语音合成，完成智能语音对话机器人   \n",
    "* 思考：问天气（调用天气API），问位置（调用高德API），问周边（调用高德周边搜索POI...）   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "5f9f4380",
   "metadata": {},
   "outputs": [],
   "source": [
    "qa = {\n",
    "    \"你好呀\":\"你也好啊，看起来心情不错呀！\",\n",
    "    \"你叫什么\":\"我是集美貌与才华一身的小度小度呀\",\n",
    "    \"设置闹钟\":\"你想设置几点的闹钟呢？现在晚上12点了，早点休息呀！\"\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "4a0f6d4b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你也好啊，看起来心情不错呀！'"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "qa.get(\"你好呀\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "92e903e4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'我是集美貌与才华一身的小度小度呀'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "qa.get(\"你叫什么\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3db6c6b1",
   "metadata": {},
   "source": [
    "> 调用电脑麦克风，将语音转换为文件\n",
    ">> 音频文件---》调用百度ASR接口"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "cf7e4b92",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on method recognize_bing in module speech_recognition:\n",
      "\n",
      "recognize_bing(audio_data, key, language='en-US', show_all=False) method of speech_recognition.Recognizer instance\n",
      "    Performs speech recognition on ``audio_data`` (an ``AudioData`` instance), using the Microsoft Bing Speech API.\n",
      "    \n",
      "    The Microsoft Bing Speech API key is specified by ``key``. Unfortunately, these are not available without `signing up for an account <https://azure.microsoft.com/en-ca/pricing/details/cognitive-services/speech-api/>`__ with Microsoft Azure.\n",
      "    \n",
      "    To get the API key, go to the `Microsoft Azure Portal Resources <https://portal.azure.com/>`__ page, go to \"All Resources\" > \"Add\" > \"See All\" > Search \"Bing Speech API > \"Create\", and fill in the form to make a \"Bing Speech API\" resource. On the resulting page (which is also accessible from the \"All Resources\" page in the Azure Portal), go to the \"Show Access Keys\" page, which will have two API keys, either of which can be used for the `key` parameter. Microsoft Bing Speech API keys are 32-character lowercase hexadecimal strings.\n",
      "    \n",
      "    The recognition language is determined by ``language``, a BCP-47 language tag like ``\"en-US\"`` (US English) or ``\"fr-FR\"`` (International French), defaulting to US English. A list of supported language values can be found in the `API documentation <https://docs.microsoft.com/en-us/azure/cognitive-services/speech/api-reference-rest/bingvoicerecognition#recognition-language>`__ under \"Interactive and dictation mode\".\n",
      "    \n",
      "    Returns the most likely transcription if ``show_all`` is false (the default). Otherwise, returns the `raw API response <https://docs.microsoft.com/en-us/azure/cognitive-services/speech/api-reference-rest/bingvoicerecognition#sample-responses>`__ as a JSON dictionary.\n",
      "    \n",
      "    Raises a ``speech_recognition.UnknownValueError`` exception if the speech is unintelligible. Raises a ``speech_recognition.RequestError`` exception if the speech recognition operation failed, if the key isn't valid, or if there is no internet connection.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(r.recognize_bing)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "b640e762",
   "metadata": {},
   "outputs": [],
   "source": [
    "import speech_recognition\n",
    "\n",
    "r = speech_recognition.Recognizer()\n",
    "\n",
    "with speech_recognition.Microphone() as source:\n",
    "    audio = r.listen(source)\n",
    "# 将数据保存到wav文件中\n",
    "with open(\"1.wav\", \"wb\") as f: \n",
    "    f.write(audio.get_wav_data(convert_rate=16000))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "409e8207",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你想设置几点的闹钟呢？现在晚上12点了，早点休息呀！\n"
     ]
    }
   ],
   "source": [
    "# coding=utf-8\n",
    "\n",
    "import sys\n",
    "import json\n",
    "import time\n",
    "\n",
    "IS_PY3 = sys.version_info.major == 3\n",
    "\n",
    "if IS_PY3:\n",
    "    from urllib.request import urlopen\n",
    "    from urllib.request import Request\n",
    "    from urllib.error import URLError\n",
    "    from urllib.parse import urlencode\n",
    "\n",
    "    timer = time.perf_counter\n",
    "else:\n",
    "    import urllib2\n",
    "    from urllib2 import urlopen\n",
    "    from urllib2 import Request\n",
    "    from urllib2 import URLError\n",
    "    from urllib import urlencode\n",
    "\n",
    "    if sys.platform == \"win32\":\n",
    "        timer = time.clock\n",
    "    else:\n",
    "        # On most other platforms the best timer is time.time()\n",
    "        timer = time.time\n",
    "\n",
    "API_KEY = '5hhk3ClVlyVDs6BoaQT75HYC'\n",
    "SECRET_KEY = 'nGhPUpw0uOxcq60auHEcB56ErhAoqMbX'\n",
    "\n",
    "# 需要识别的文件\n",
    "AUDIO_FILE = '1.wav'  # 只支持 pcm/wav/amr 格式，极速版额外支持m4a 格式\n",
    "# 文件格式\n",
    "FORMAT = AUDIO_FILE[-3:];  # 文件后缀只支持 pcm/wav/amr 格式，极速版额外支持m4a 格式\n",
    "\n",
    "CUID = '123456PYTHON';\n",
    "# 采样率\n",
    "RATE = 16000;  # 固定值\n",
    "\n",
    "# 普通版\n",
    "\n",
    "DEV_PID = 1537;  # 1537 表示识别普通话，使用输入法模型。根据文档填写PID，选择语言及识别模型\n",
    "ASR_URL = 'http://vop.baidu.com/server_api'\n",
    "SCOPE = 'audio_voice_assistant_get'  # 有此scope表示有asr能力，没有请在网页里勾选，非常旧的应用可能没有\n",
    "\n",
    "#测试自训练平台需要打开以下信息， 自训练平台模型上线后，您会看见 第二步：“”获取专属模型参数pid:8001，modelid:1234”，按照这个信息获取 dev_pid=8001，lm_id=1234\n",
    "# DEV_PID = 8001 ;   \n",
    "# LM_ID = 1234 ;\n",
    "\n",
    "# 极速版 打开注释的话请填写自己申请的appkey appSecret ，并在网页中开通极速版（开通后可能会收费）\n",
    "\n",
    "#DEV_PID = 80001\n",
    "#ASR_URL = 'http://vop.baidu.com/pro_api'\n",
    "#SCOPE = 'brain_enhanced_asr'  # 有此scope表示有asr能力，没有请在网页里开通极速版\n",
    "\n",
    "# 忽略scope检查，非常旧的应用可能没有\n",
    "# SCOPE = False\n",
    "\n",
    "\n",
    "# 极速版\n",
    "\n",
    "class DemoError(Exception):\n",
    "    pass\n",
    "\n",
    "\n",
    "\"\"\"  TOKEN start \"\"\"\n",
    "\n",
    "TOKEN_URL = 'http://aip.baidubce.com/oauth/2.0/token'\n",
    "\n",
    "\n",
    "def fetch_token():\n",
    "    params = {'grant_type': 'client_credentials',\n",
    "              'client_id': API_KEY,\n",
    "              'client_secret': SECRET_KEY}\n",
    "    post_data = urlencode(params)\n",
    "    if (IS_PY3):\n",
    "        post_data = post_data.encode('utf-8')\n",
    "    req = Request(TOKEN_URL, post_data)\n",
    "    try:\n",
    "        f = urlopen(req)\n",
    "        result_str = f.read()\n",
    "    except URLError as err:\n",
    "        print('token http response http code : ' + str(err.code))\n",
    "        result_str = err.read()\n",
    "    if (IS_PY3):\n",
    "        result_str = result_str.decode()\n",
    "\n",
    " #   print(result_str)\n",
    "    result = json.loads(result_str)\n",
    " #   print(result)\n",
    "    if ('access_token' in result.keys() and 'scope' in result.keys()):\n",
    "        if SCOPE and (not SCOPE in result['scope'].split(' ')):  # SCOPE = False 忽略检查\n",
    "            raise DemoError('scope is not correct')\n",
    "    #    print('SUCCESS WITH TOKEN: %s ; EXPIRES IN SECONDS: %s' % (result['access_token'], result['expires_in']))\n",
    "        return result['access_token']\n",
    "    else:\n",
    "        raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response')\n",
    "\n",
    "\n",
    "\"\"\"  TOKEN end \"\"\"\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    token = fetch_token()\n",
    "\n",
    "    \"\"\"\n",
    "    httpHandler = urllib2.HTTPHandler(debuglevel=1)\n",
    "    opener = urllib2.build_opener(httpHandler)\n",
    "    urllib2.install_opener(opener)\n",
    "    \"\"\"\n",
    "\n",
    "    speech_data = []\n",
    "    with open(AUDIO_FILE, 'rb') as speech_file:\n",
    "        speech_data = speech_file.read()\n",
    "    length = len(speech_data)\n",
    "    if length == 0:\n",
    "        raise DemoError('file %s length read 0 bytes' % AUDIO_FILE)\n",
    "\n",
    "    params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID}\n",
    "    #测试自训练平台需要打开以下信息\n",
    "    #params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID, 'lm_id' : LM_ID}\n",
    "    params_query = urlencode(params);\n",
    "\n",
    "    headers = {\n",
    "        'Content-Type': 'audio/' + FORMAT + '; rate=' + str(RATE),\n",
    "        'Content-Length': length\n",
    "    }\n",
    "\n",
    "    url = ASR_URL + \"?\" + params_query\n",
    "#    print(\"url is\", url);\n",
    "#    print(\"header is\", headers)\n",
    "    # print post_data\n",
    "    req = Request(ASR_URL + \"?\" + params_query, speech_data, headers)\n",
    "    try:\n",
    "        begin = timer()\n",
    "        f = urlopen(req)\n",
    "        result_str = f.read()\n",
    "    #    print(\"Request time cost %f\" % (timer() - begin))\n",
    "    except  URLError as err:\n",
    "        print('asr http response http code : ' + str(err.code))\n",
    "        result_str = err.read()\n",
    "\n",
    "    if (IS_PY3):\n",
    "        result_str = str(result_str, 'utf-8')  #result_str已经是字符串（字典）\n",
    "   # print(eval (result_str)[\"result\"][0][:-1])  #eval（）将str-->dict\n",
    "    print(qa.get(eval (result_str)[\"result\"][0][:-1]))\n",
    "    with open(\"result.txt\", \"w\") as of:\n",
    "        of.write(result_str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "584ec705",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
